Security News
Research
Supply Chain Attack on Rspack npm Packages Injects Cryptojacking Malware
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
@swagger-api/apidom-core
Advanced tools
@swagger-api/apidom-core is a core library for working with API definitions in various formats such as OpenAPI, AsyncAPI, and JSON Schema. It provides tools for parsing, transforming, and serializing API documents, making it easier to work with these specifications programmatically.
Parsing API Documents
This feature allows you to parse API documents written in OpenAPI, AsyncAPI, or JSON Schema formats. The code sample demonstrates parsing an OpenAPI document and logging the parsed result.
const { parse } = require('@swagger-api/apidom-core');
const openApiDocument = `
openapi: 3.0.0
info:
title: Sample API
version: 0.1.0
paths:
/example:
get:
summary: Example endpoint
responses:
'200':
description: Successful response
`;
parse(openApiDocument).then((parsedDoc) => {
console.log(parsedDoc);
}).catch((error) => {
console.error('Error parsing document:', error);
});
Transforming API Documents
This feature allows you to apply transformations to API documents. The code sample demonstrates transforming an OpenAPI document by changing its title.
const { transform } = require('@swagger-api/apidom-core');
const openApiDocument = `
openapi: 3.0.0
info:
title: Sample API
version: 0.1.0
paths:
/example:
get:
summary: Example endpoint
responses:
'200':
description: Successful response
`;
const transformation = (doc) => {
doc.info.title = 'Transformed API';
return doc;
};
transform(openApiDocument, transformation).then((transformedDoc) => {
console.log(transformedDoc);
}).catch((error) => {
console.error('Error transforming document:', error);
});
Serializing API Documents
This feature allows you to serialize parsed API documents back into their respective formats. The code sample demonstrates serializing a parsed OpenAPI document.
const { serialize } = require('@swagger-api/apidom-core');
const parsedDoc = {
openapi: '3.0.0',
info: {
title: 'Sample API',
version: '0.1.0'
},
paths: {
'/example': {
get: {
summary: 'Example endpoint',
responses: {
'200': {
description: 'Successful response'
}
}
}
}
}
};
serialize(parsedDoc).then((serializedDoc) => {
console.log(serializedDoc);
}).catch((error) => {
console.error('Error serializing document:', error);
});
swagger-parser is a powerful API parsing library that supports OpenAPI 3.0, OpenAPI 2.0 (Swagger), and JSON Schema. It provides similar functionalities to @swagger-api/apidom-core, such as parsing, validating, and dereferencing API documents. However, it is more focused on validation and dereferencing.
openapi-typescript is a tool that generates TypeScript types from OpenAPI 3.0 definitions. While it does not provide parsing or transformation capabilities like @swagger-api/apidom-core, it is useful for generating type-safe code based on API specifications.
swagger-client is a JavaScript client for interacting with Swagger/OpenAPI documents. It allows you to fetch, parse, and interact with API definitions. Compared to @swagger-api/apidom-core, swagger-client is more focused on providing a client interface for API interaction rather than document transformation.
apidom-core
is a package that contains tools for manipulating the ApiDOM structures.
You can install this package via npm CLI by running the following command:
$ npm install @swagger-api/apidom-core
Base namespace consists of four higher order elements implemented on top of primitive ones.
import { createNamespace } from '@swagger-api/apidom-core';
const namespace = createNamespace();
const objectElement = new namespace.elements.Object();
const commentElement = new namespace.elements.Comment();
It's possible to create namespace instances using another namespaces.
import { createNamespace } from '@swagger-api/apidom-core';
import openApi3_1Namespace from '@swagger-api/apidom-ns-openapi-3-1';
const namespace = createNamespace(openApi3_1Namespace);
const objectElement = new namespace.elements.Object();
const openApiElement = new namespace.elements.OpenApi3_1();
When namespace instance is created in this way, it will extend the base namespace with the namespace provided as an argument.
This package exposes predicates for all primitive elements and all higher order elements that are part of the base namespace.
import { CommentElement, isCommentElement } from '@swagger-api/apidom-core';
const commentElement = new CommentElement();
isCommentElement(commentElement); // => true
Predicate helpers helps in building predicates for this and other packages.
import { createPredicate } from '@swagger-api/apidom-core';
const isMyElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element) =>
element instanceof MyElement ||
(hasBasicElementProps(element) && isElementType('myElement', element) && primitiveEq('object', element));
},
);
Transclusion is the inclusion of one ApiDOM fragment into another ApiDOM fragment. Our transcluder does exactly that and is based on mutating algorithm.
import { transclude, ArrayElement, NumberElement } from '@swagger-api/apidom-core';
const element = new ArrayElement([1, 2, 3]);
const search = element.get(1);
const replace = new NumberElement(4);
transclude(search, replace, element); // => ArrayElement<[1, 4, 3]>
When multiple transclusions are going to be performed use Transcluder stamp for optimal performance.
import { Transcluder, ArrayElement, NumberElement } from '@swagger-api/apidom-core';
const element = new ArrayElement([1, 2, 3]);
const search = element.get(1);
const replace = new NumberElement(4);
const transcluder = Transcluder({ element });
transcluder.transclude(search, replace); // => ArrayElement<[1, 4, 3]>
mergeRight
and mergeLeft
functions merge members of two or more ObjectElements shallowly
and handles shallow merging of ArrayElements as well.
Merges two ApiDOM elements target and source shallowly, returning a new merged ApiDOM element with the elements from both target and source. If an element at the same key is present for both target and source, the value from source will appear in the result. Merging creates a new ApiDOM element, so that neither target nor source is modified (operation is immutable).
import { mergeRight, ObjectElement } from '@swagger-api/apidom-core';
const x = new ObjectElement({
foo: { bar: 3 },
});
const y = new ObjectElement({
foo: { baz: 4 },
quux: 5,
});
const output = mergeRight(x, y);
// =>
// ObjectElement({
// foo: ObjectElement({
// baz: 4,
// }),
// quux: 5,
// })
Merges shallowly any number of ApiDOM elements into a single ApiDOM element.
import { mergeRight, ObjectElement } from '@swagger-api/apidom-core';
const foobar = new ObjectElement({ foo: { bar: 3 } });
const foobaz = new ObjectElement({ foo: { baz: 4 } });
const bar = new ObjectElement({ bar: 'yay!' });
const output = mergeRight.all([ foobar, foobaz, bar ]);
// => ObjectElement({ foo: { baz: 4 }, bar: 'yay!' })
Merges two ApiDOM elements source and target shallowly, returning a new merged ApiDOM element with the elements from both target and source. If an element at the same key is present for both target and source, the value from source will appear in the result. Merging creates a new ApiDOM element, so that neither target nor source is modified (operation is immutable).
import { mergeLeft, ObjectElement } from '@swagger-api/apidom-core';
const x = new ObjectElement({
foo: { bar: 3 },
});
const y = new ObjectElement({
foo: { baz: 4 },
quux: 5,
});
const output = mergeLeft(x, y);
// =>
// ObjectElement({
// foo: ObjectElement({
// bar: 3,
// }),
// quux: 5,
// })
Merges shallowly any number of ApiDOM elements into a single ApiDOM element.
import { mergeLeft, ObjectElement } from '@swagger-api/apidom-core';
const foobar = new ObjectElement({ foo: { bar: 3 } });
const foobaz = new ObjectElement({ foo: { baz: 4 } });
const bar = new ObjectElement({ bar: 'yay!' });
const output = mergeLeft.all([ foobar, foobaz, bar ]);
// => ObjectElement({ foo: { baz: 3 }, bar: 'yay!' })
mergeRight
and mergeLeft
take the same options as deepmerge, except for customMerge
and clone
.
deepmerge
functions merged members of two or more ObjectElements deeply
and handles deep merging of ArrayElements as well. This deep merge implementation
is a functional equivalent of deepmerge
that works equivalently on ApiDOM structures.
Merges two ApiDOM elements target and source deeply, returning a new merged ApiDOM element with the elements from both target and source. If an element at the same key is present for both target and source, the value from source will appear in the result. Merging creates a new ApiDOM element, so that neither target nor source is modified (operation is immutable).
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const x = new ObjectElement({
foo: { bar: 3 },
array: [
{
does: 'work',
too: [1, 2, 3],
},
],
});
const y = new ObjectElement({
foo: { baz: 4 },
quux: 5,
array: [
{
does: 'work',
too: [4, 5, 6],
},
{
really: 'yes',
},
],
});
const output = deepmerge(x, y);
// =>
// ObjectElement({
// foo: ObjectElement({
// bar: 3,
// baz: 4,
// }),
// array: ArrayElement([
// ObjectElement({
// does: 'work',
// too: [1, 2, 3],
// }),
// ObjectElement({
// does: 'work',
// too: [4, 5, 6],
// }),
// ObjectElement({
// really: 'yes',
// }),
// ]),
// quux: 5,
// })
Merges deeply any number of ApiDOM elements into a single ApiDOM element.
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const foobar = new ObjectElement({ foo: { bar: 3 } });
const foobaz = new ObjectElement({ foo: { baz: 4 } });
const bar = new ObjectElement({ bar: 'yay!' });
const output = deepmerge.all([ foobar, foobaz, bar ]);
// => ObjectElement({ foo: { bar: 3, baz: 4 }, bar: 'yay!' })
There are multiple ways to merge two ArrayElements, below are a few examples, but you can also create your own custom function.
Your arrayElementMerge
function will be called with three arguments: a target
ArrayElement, the source
ArrayElement,
and an options
object.
import { deepmerge, ArrayElement } from '@swagger-api/apidom-core';
const arrayElementMerge = (destination, source, options) => source;
const target = new ArrayElement([1, 2, 3]);
const source = new ArrayElement([3, 2, 1]);
const output = deepmerge(target, source, { arrayElementMerge });
// => ArrayElement([3, 2, 1]);
There are multiple ways to merge two ObjectElements, below are a few examples, but you can also create your own custom function.
Your objectElementMerge
function will be called with three arguments: a target
ObjectElement, the source
ObjectElement,
and an options
object.
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const objectElementMerge = (destination, source, options) => source;
const target = new ObjectElement({a: 1, b: 2});
const source = new ObjectElement({c: 3, d: 4});
const output = deepmerge(target ,source, { objectElementMerge });
// => ObjectElement({c: 3, d: 4});
By default, deepmerge clones every member from ObjectElement and ArrayElement. You may not want this, if your ObjectElements are of special types, and you want to copy the whole ObjectElement instead of just copying its member.
You can accomplish this by passing in a function for the isMergeableElement
option.
import { deepmerge, ObjectElement, isObjectElement } from '@swagger-api/apidom-core';
class CustomObjectElement extends ObjectElement {
element = 'custom';
}
const instantiatedCustomObjectElement = new CustomObjectElement({ special: 'oh yeah' });
const target = new ObjectElement({
someProperty: {
cool: 'oh for sure',
},
});
const source = new ObjectElement({
someProperty: instantiatedCustomObjectElement,
});
const isMergeableElement = (element: Element) => isObjectElement(element) && !(element instanceof CustomObjectElement);
const output = deepmerge(target, source, {
isMergeableElement,
});
// output.get('someProperty').get('cool'); // => undefined
// output.get('someProperty').get('special'); // => 'oh yeah'
// output.get('someProperty') instanceof CustomObjectElement // => true
Specifies a function which can be used to override the default merge behavior for a member, based on the key name.
The customMerge
function will be passed the key for each member, and should return the function which should
be used to merge the values for that member.
It may also return undefined, in which case the default merge behaviour will be used.
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const alex = new ObjectElement({
name: {
first: 'Alex',
last: 'Alexson'
},
pets: ['Cat', 'Parrot']
});
const tony = new ObjectElement({
name: {
first: 'Tony',
last: 'Tonison'
},
pets: ['Dog']
});
const mergeNames = (nameA: ObjectElement, nameB: ObjectElement) =>
new StringElement(`${toValue(nameA.get('first'))} and ${toValue(nameB.get('first'))}`);
const customMerge = (key: Element) => (toValue(key) === 'name' ? mergeNames : undefined);
const output = deepmerge(alex, tony, { customMerge });
// output.get('name'); // => StrignElement('Alex and Tony')
// output.get('pets'); // => ArrayElement(['Cat', 'Parrot', 'Dog'])
Specifies a function which can be used to override the default metadata merge behavior.
The customMetaMerge
function will be passed target and source metadata. If not specified,
the default behavior is to deep copy metadata from target to new merged element.
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const alex = new ObjectElement({ name: { first: 'Alex' } }, { metaKey: true });
const tony = new ObjectElement({ name: { first: 'Tony' } }, { metaKey: false });
const customMetaMerge = (targetMeta, sourceMeta) => deepmerge(targetMeta, sourceMeta);
const output = deepmerge(alex, tony, { customMetaMerge });
// output.meta.get('metaKey') // => BooleanElement(false)
Specifies a function which can be used to override the default attributes merge behavior.
The customAttributesMerge
function will be passed target and source attributes. If not specified,
the default behavior is to deep copy attributes from target to new merged element.
import { deepmerge, ObjectElement } from '@swagger-api/apidom-core';
const alex = new ObjectElement({ name: { first: 'Alex' } }, undefined, { attributeKey: true });
const tony = new ObjectElement({ name: { first: 'Tony' } }, undefined, { attributeKey: false });
const customAttributesMerge = (targetMeta, sourceMeta) => deepmerge(targetMeta, sourceMeta);
const output = deepmerge(alex, tony, { customAttributesMerge });
// output.attributs.get('attributeKey') // => BooleanElement(false)
Defaults to true
.
If clone
is false then child elements will be copied directly instead of being cloned.
Refractor is a special layer inside the base namespace that can transform JavaScript structures into generic ApiDOM structures built from elements of this base namespace.
Refracting JavaScript structures:
import { ObjectElement } from '@swagger-api/apidom-core';
const object = {
title: 'my title',
description: 'my description',
version: '0.1.0',
};
ObjectElement.refract(object); // => ObjectElement({ title, description, version })
import { CommentElement } from '@swagger-api/apidom-core';
const comment = 'this is comment';
CommentElement.refract(comment); // => CommentElement('this is comment')
Refractors can accept plugins as a second argument of refract static method.
import { ObjectElement, StringElement } from '@swagger-api/apidom-core';
const object = { a: 'b' };
const plugin = ({ predicates, namespace }) => ({
name: 'plugin',
pre() {
console.dir('runs before traversal');
},
visitor: {
ObjectElement(objectElement) {
objectElement.getMember('a').value = new StringElement('c');
},
},
post() {
console.dir('runs after traversal');
},
});
ObjectElement.refract(object, { plugins: [plugin] }); // => ObjectElement({ a = 'c' })
You can define as many plugins as needed to enhance the resulting namespaced ApiDOM structure. If multiple plugins with the same visitor method are defined, they run in parallel (just like in Babel).
apidom
package comes with refractorPluginElementIdentity
. When used, this plugin will
assign unique ID to all elements in ApiDOM tree.
import { refractorPluginElementIdentity, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = ObjectElement.refract({ a: 'b' }, {
plugins: [
refractorPluginElementIdentity(),
]
});
objectElement.id; // 8RaWF9
objectElement.getMember('a').key.id; // NdHHV7
objectElement.getMember('a').value.id; // rFGVFP
You can configure the plugin to generate unique IDs in the specific length:
import { refractorPluginElementIdentity, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = ObjectElement.refract({ a: 'b' }, {
plugins: [
refractorPluginElementIdentity({ length: 36}),
]
});
objectElement.id; // OnReGGrO7fMd9ztacvGfwGbOdGKuOFLiQQ1W
objectElement.getMember('a').key.id; // BN6rHsmqI56SMQ1elshtbgRVECtEWNYS9lmd
objectElement.getMember('a').value.id; // Ki4tWmf9xw9Lwb8MxkXJq1uONmJrmhXifmsI
apidom
package comes with refractorPluginSemanticElementIdentity
. When used, this plugin will
assign unique ID to all non-primitive elements in ApiDOM tree. Primitive elements include
ObjectElement
, ArrayElement
, StringElement
, BooleanElement
, NullElement
and NumberElement
.
import { refractorPluginSemanticElementIdentity, ObjectElement } from '@swagger-api/apidom-core';
import { InfoElement } from '@swagger-api/apidom-ns-openapi-3-1';
const infoElement = InfoElement.refract({ title: 'title' });
const objectElement = ObjectElement.refract({ a: 'b', info: infoElement }, {
plugins: [
refractorPluginSemanticElementIdentity(),
]
});
objectElement.id; // ''
objectElement.getMember('a').key.id; // ''
objectElement.getMember('a').value.id; // ''
objectElement.getMember('info').key.id; // ''
objectElement.getMember('info').value.id; // '8RaWF9'
You can configure the plugin to generate unique IDs in the specific length:
import { refractorPluginSemanticElementIdentity, ObjectElement } from '@swagger-api/apidom-core';
import { InfoElement } from '@swagger-api/apidom-ns-openapi-3-1';
const infoElement = InfoElement.refract({ title: 'title' });
const objectElement = ObjectElement.refract({ a: 'b', info: infoElement }, {
plugins: [
refractorPluginSemanticElementIdentity({ length: 36 }),
]
});
objectElement.id; // ''
objectElement.getMember('a').key.id; // ''
objectElement.getMember('a').value.id; // ''
objectElement.getMember('info').key.id; // ''
objectElement.getMember('info').value.id; // 'OnReGGrO7fMd9ztacvGfwGbOdGKuOFLiQQ1W'
apidom
comes with its own traversal algorithm along with couple of convenient abstractions on top of it.
visit will walk through an AST using a depth first traversal, calling the visitor's enter function at each node in the traversal, and calling the leave function after visiting that node and all of its child nodes.
By returning different values from the enter and leave functions, the behavior of the visitor can be altered, including skipping over a sub-tree of the ApiDOM (by returning false), editing the ApiDOM by returning a value or null to remove the value, or to stop the whole traversal by returning BREAK.
When using visit
to edit an ApiDOM, the original ApiDOM will not be modified, and
a new version of the ApiDOM with the changes applied will be returned from the
visit function.
import { visit, ObjectElement, NumberElement } from '@swagger-api/apidom-core';
const visitor = {
NumberElement(numberElement) {
return new NumberElement(2);
},
};
const element = new ObjectElement({ a: 1 });
const newElement = visit(element, visitor); // => ObjectElement<{a: 2}>
This function originally comes from @swagger-api/apidom-ast package
and is originally designed to work with CST. apidom
package
imports it, specializes it to work with ApiDOM and re-export it.
All following algorithms are based on visit
function.
Finds all elements matching the predicate.
import { ObjectElement, filter, isNumberElement } from '@swagger-api/apidom-core'
const objElement = new ObjectElement({ a: 'b', c: 2 });
filter(isNumberElement, objElement); // => ArraySlice<[NumberElement<2>]>
Find first element that satisfies the provided predicate.
import { ObjectElement, find, isMemberElement } from '@swagger-api/apidom-core'
const objElement = new ObjectElement({ a: 'b', c: 2 });
find(isNumberElement, objElement); // => NumberElement<2>
ApiDOM nodes can be associated with source maps. This function finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
import { findAtOffset } from '@swagger-api/apidom-core'
findAtOffset(3, elementWithSourceMaps); // => returns most inner node at offset 3
Complement of filter.
import { ArrayElement, reject, isNumberElement } from '@swagger-api/apidom-core'
const arrayElement = new ArrayElement([1, 'a']);
reject(isNumberElement, arrayElement); // => ArraySlice<[StringElement<'a'>]>
Tests whether at least one element passes the predicate.
import { ArrayElement, some, isNumberElement } from '@swagger-api/apidom-core'
const arrayElement = new ArrayElement([1, 'a']);
some(isNumberElement, arrayElement); // => true
Executes the callback on this element and all descendants.
import { ArrayElement, traverse } from '@swagger-api/apidom-core'
const arrayElement = new ArrayElement([1, 'a']);
traverse(console.dir, arrayElement); // => prints ArrayElement, NumberElement, StringElement in this order
The execution of the callback can be controlled further by providing a predicate.
import { ArrayElement, traverse, isNumberElement } from '@swagger-api/apidom-core'
const arrayElement = new ArrayElement([1, 'a']);
traverse({ callback: console.dir, predicate: isNumberElement }, arrayElement); // => prints NumberElement<1>
Computes upwards edges from every child to its parent.
import { parents, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = new ObjectElement({ key: 'value' });
const memberElement = objectElement.getMember('key');
const { key: keyElement, value: valueElement } = memberElement;
const parentEdges = parents(objectElement); // => WeakMap<ChildElement, ParentElement>
parentEdges.get(memberElement) === objectElement; // => true
parentEdges.get(keyElement) === memberElement; // => true
parentEdges.get(valueElement) === memberElement; // => true
import { parents, ArrayElement, StringElement } from '@swagger-api/apidom-core';
const itemElement1 = new StringElement('item1');
const itemElement2 = new StringElement('item2');
const arrayElement = new ArrayElement([itemElement1, itemElement2]);
const parentEdges = parents(arrayElement); // => WeakMap<ChildElement, ParentElement>
parentEdges.get(itemElement1) === arrayElement; // => true
parentEdges.get(itemElement2) === arrayElement; // => true
Following functions transforms ApiDOM between its various forms. All transformers (except toValue
) can accept
ApiDOM namespace instance as a second argument.
Transforms data to an Element from a particular namespace.
From a refracted string form:
import { from } from '@swagger-api/apidom-core';
const refractedString = '{"element":"number","content":1}';
from(refractedString); // => NumberElement<1>
From a refracted form:
import { from } from '@swagger-api/apidom-core';
const refracted = { element: 'number', content: 1 };
from(refracted); // => NumberElement<1>
From a JavaScript form:
import { from } from '@swagger-api/apidom-core';
const javascriptForm = 1;
from(javascriptForm); // => NumberElement<1>
Transforms the ApiDOM into JavaScript POJO. This POJO would be the result of interpreting the ApiDOM into JavaScript structure. This function can handle cycles in ApiDOM structure.
import { toValue, ObjectElement } from '@swagger-api/apidom-core';
const objElement = new ObjectElement({ a: 'b' });
toValue(objElement); // => { a: 'b' }
Transforms the ApiDOM into JSON string.
import { toJSON, ObjectElement } from '@swagger-api/apidom-core';
const objElement = new ObjectElement({ a: 'b' });
toJSON(objElement); // => '{"a":"b"}'
Transforms the ApiDOM into JSON string.
import { toYAML, ObjectElement } from '@swagger-api/apidom-core';
const objElement = new ObjectElement({ a: 'b' });
toYAML(objElement);
/**
* %YAML 1.2
* ---
*
* "a": "b"
*/
Creates a refract representation of the an Element.
import { dehyrate, NumberElement } from '@swagger-api/apidom-core';
const numberElement = new NumberElement(1);
dehyrate(numberElement); // => { element: 'number', content: 1 }
Transforms ApiDOM into symbolic expression.
import { sexprs, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = new ObjectElement({ a: 1 });
sexprs(objectElement);
// =>
// (ObjectElement
// (MemberElement
// (StringElement)
// (NumberElement)))
Create a refracted string representation of an Element.
import { toString, NumberElement } from '@swagger-api/apidom-core';
const numberElement = new NumberElement(1);
toString(numberElement); // => '{"element":"number","content":1}'
Following functions provide mechanism for creating shallow and deep copies of ApiDOM elements.
Creates shallow clone of ApiDOM element.
import { cloneShallow, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = new ObjectElement({ a: 'b' });
const objectElementShallowClone = cloneShallow(objectElement);
Creates deep clone of ApiDOM Element.
import { cloneDeep, ObjectElement } from '@swagger-api/apidom-core';
const objectElement = new ObjectElement({ a: 'b' });
const objectElementDeepClone = cloneDeep(objectElement);
1.0.0-beta.5 (2024-12-16)
FAQs
Tools for manipulating ApiDOM structures.
The npm package @swagger-api/apidom-core receives a total of 450,145 weekly downloads. As such, @swagger-api/apidom-core popularity was classified as popular.
We found that @swagger-api/apidom-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.
Security News
Sonar’s acquisition of Tidelift highlights a growing industry shift toward sustainable open source funding, addressing maintainer burnout and critical software dependencies.